package com.boby.homecamera.webserver.websocket

import android.os.Handler
import android.os.HandlerThread
import com.boby.homecamera.constant.Constant
import com.boby.homecamera.data.WebSocketData
import com.boby.homecamera.db.VideoEventTable
import com.boby.homecamera.helper.AudioPlayHelper
import com.boby.homecamera.service.MainService
import com.boby.homecamera.util.JwtUtil.validateToken
import com.boby.lib_common.util.BLog
import com.boby.lib_common.util.JsonUtil

import kotlinx.coroutines.Runnable
import org.java_websocket.WebSocket
import org.java_websocket.handshake.ClientHandshake
import org.java_websocket.server.WebSocketServer
import org.json.JSONObject
import java.lang.Exception
import java.net.InetSocketAddress
import java.nio.ByteBuffer

class MyWebSocketServer(port: Int) : WebSocketServer(InetSocketAddress(port)) {
    private val handler:Handler
    private val TAG = "MyWebSocketServer"
    init {
        isReuseAddr = true
        isDaemon = true
        val handlerThread = HandlerThread("websocket")
        handlerThread.start()
        handler = Handler(handlerThread.looper)
    }
    override fun onOpen(conn: WebSocket, handshake: ClientHandshake) {
        val query = handshake.resourceDescriptor // 例如 /ws?token=xxx
        val params = parseQueryParams(query)

        val token = params["token"]
        val user = validateToken(token)
        if (user.isNullOrEmpty()) {
            conn.close(1008, "认证失败")
            BLog.d(TAG, "连接被拒绝：密码错误")
            return
        }

        BLog.d(TAG, "连接成功：来自 ${conn.remoteSocketAddress}")
        conn.send(WebSocketData(Constant.WebSocketCode.CONNECT_ERROR, null).toString())
        addClient(conn)
    }

    override fun onClose(p0: WebSocket?, p1: Int, p2: String?, p3: Boolean) {
        BLog.d(TAG, "连接断开：来自 ${p0?.remoteSocketAddress}")
        removeClient(p0)
    }

    override fun onMessage(client: WebSocket?, msg: String?) {
        if (msg.isNullOrEmpty()) {
            return
        }
       try {
           val jsonObject = JSONObject(msg)
           if(jsonObject.has("code")){
               val code  = jsonObject.getInt("code")
               handlerMsg(code,jsonObject,client)
           }

       }catch (e: Exception){
         e.printStackTrace()
       }

    }

    override fun onMessage(conn: WebSocket?, message: ByteBuffer) {
        super.onMessage(conn, message)

//        val data = message.array()
        val data =  message.array().copyOf()
//        BLog.d(TAG, "audioCall: onMessage ${data.size}")

        audioPlayHelper?.run {
//            if(webSocket == conn){
                onAudioFrame(data)
//            }
        }
    }

    override fun onError(p0: WebSocket?, p1: Exception?) {
        removeClient(p0)
    }

    override fun onStart() {

    }

    // 简单解析 URL 参数
    private fun parseQueryParams(resource: String): Map<String, String> {
        val result = mutableMapOf<String, String>()
        val idx = resource.indexOf("?")
        if (idx != -1 && idx + 1 < resource.length) {
            val query = resource.substring(idx + 1)
            for (pair in query.split("&")) {
                val parts = pair.split("=")
                if (parts.size == 2) {
                    result[parts[0]] = parts[1]
                }
            }
        }
        return result
    }

    private fun handlerMsg(code:Int,jsonObject: JSONObject,client: WebSocket?){
        when(code){
            Constant.WebSocketCode.FLASHLIGHT_ON ->  flashlight(true)
            Constant.WebSocketCode.FLASHLIGHT_OFF ->  flashlight(false)
            Constant.WebSocketCode.VOICE_CALL_START ->  audioCall(true,client)
            Constant.WebSocketCode.VOICE_CALL_END ->  audioCall(false,client)
        }
    }

    private val clients = HashMap<WebSocket, ClientWebSocket>()

    @Synchronized
    private fun addClient(client: WebSocket) {
        val webSocketClient = ClientWebSocket(client)
        clients.put(client, webSocketClient)
    }

    @Synchronized
    private fun removeClient(client: WebSocket?) {
        if (client == null) {
            return
        }
        val removeClient = clients.remove(client)
        removeClient?.close()
    }

    fun sendVideoEvent(videoEvent: VideoEventTable.VideoEvent){
        sendMessage(WebSocketData(Constant.WebSocketCode.EVENT_MSG, JsonUtil.toJson(videoEvent)),500)
    }
    fun sendMessage(message: WebSocketData,delay:Long = 0) {
        handler.postDelayed({
            sendMsg(JsonUtil.toJson( message))
        },delay)

    }

    @Synchronized
    private fun sendMsg(message: String) {
        val iterator = clients.iterator()
        while (iterator.hasNext()){
            val client = iterator.next()
            client.value.send(message)
        }
    }

    private fun flashlight(turnOn: Boolean){
        handler.removeCallbacks(turnOffFlashlightRunnable)
        if(turnOn){
            handler.post {
                MainService.recordServer?.enableLantern()
            }
            handler.postDelayed(turnOffFlashlightRunnable,30000)
        }else{
            handler.postDelayed(turnOffFlashlightRunnable,1)
        }

    }

    private val turnOffFlashlightRunnable = Runnable {
        MainService.recordServer?.disableLantern()
    }
    private var audioPlayHelper: AudioPlayHelper? = null
    private fun audioCall(isStart: Boolean,client: WebSocket?){
        BLog.d(TAG, "audioCall: $isStart")
        if(isStart){
            audioPlayHelper = AudioPlayHelper(client)
            audioPlayHelper?.start()
        }else{
            audioPlayHelper?.stop()
            audioPlayHelper = null
        }
    }

}